package org.sippr.schedule;


import com.fasterxml.jackson.core.JsonProcessingException;
import org.sippr.pojo.CreationImgAi;
import org.sippr.pojo.CreationImgSketch;
import org.sippr.pojo.Server;
import org.sippr.pojo.TaskQueue;
import org.sippr.service.*;
import org.sippr.utils.SdRequestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@Component
public class ScheduledTasks {
    @Autowired
    private TaskQueueService taskQueueService;
    @Autowired
    private ServerService serverService;
    @Autowired
    private CreationStyleService creationStyleService;
    @Autowired
    private CreationImgSketchService creationImgSketchService;
    @Autowired
    private CreationWordCueService creationWordCueService;
    @Autowired
    private CreationWordNegativeService creationWordNegativeService;
    @Autowired
    private CreationImgAiService creationImgAiService;
    @Autowired
    private CreationService creationService;
    @Value("${file.upload.path}")
    private String baseDirectory;


    //更新服务器状态，主要是是否在线，不关心它是否在工作
    @Scheduled(fixedRate = 10000)
    public void updateServerState() {
        List<Server> servers = serverService.list();
        for (Server server : servers) {
            Boolean isOnLine = SdRequestUtils.IsOnLine(server.getAddress());
            //1在线，2无法访问，
            if (!isOnLine && server.getState() == 1) {
                server.setState((short) 2);
                serverService.setServerNotOnLine(server.getId());
                System.out.println(server.getAddress() + "服务器下线");
            } else if (isOnLine && server.getState() == 2) {
                server.setState((short) 1);
                serverService.setServiceOnLine(server.getId());
                System.out.println(server.getAddress() + "服务器上线");
            }

        }

    }


    //定时处理Sd任务队列
    @Scheduled(fixedRate = 3000)
    public void processSdQueue() throws IOException, InterruptedException {
        //判断是否有未执行的任务，如果没有，直接返回
        List<TaskQueue> tasks = taskQueueService.findWatingTask();
        if (tasks.isEmpty())
            return;
        //如果有未执行的任务
        System.out.println("检测到" + tasks.size() + "个任务等待执行！");
        //遍历服务器，找到空闲服务器
        List<Server> servers = serverService.findOnLineServers();
        if (servers.isEmpty()) {
            //报警
            //如果没有服务器在线，那么发出警告
            return;
        }
        //先判断服务器是否在线
        //如果在线，再判断服务器是否繁忙
        for (TaskQueue task : tasks) {
            Server idleServer = null;
            for (Server server : servers) {
                Boolean busy = SdRequestUtils.IsBusy(server.getAddress());
                //如果繁忙，判断下一个，直至找到在线且空闲的服务器
                if (!busy) {
                    //找到空闲机器，终止遍历
                    idleServer = server;
                    break;
                } else {
                    System.out.println("服务器" + server.getAddress() + "正忙");
                }
            }
            if (idleServer != null) {
                System.out.println("检测到空闲服务器" + idleServer.getAddress());

                Integer creationId = task.getCreationId();
                //    0代表纯文字，1代表草图和文字
                Integer creationCate = task.getCreation().getCate();

                //组装路径，路径为“\gen-ai-img\projectId”
                String pngName = UUID.randomUUID() + ".png";
                Path dir = Paths.get(baseDirectory, "\\gen-ai-img");
                dir = Paths.get(dir.toString(), task.getCreation().getProjectId().toString());
                if (!Files.exists(dir)) {
                    Files.createDirectories(dir);
                }
                String aiImgPngPath = dir.resolve(pngName).toString();
                //根据文生效果图还是图生效果图，执行不同的操作

                Server finalIdleServer = idleServer;
                taskQueueService.setStateWorkiing(task.getId());
                TimeUnit.SECONDS.sleep(1);
                if (creationCate == 1) {
                    CreationImgSketch creationImgSketch = creationImgSketchService.findById(task.getCreation().getSketchId());
                    if (creationImgSketch == null)//这个任务，有问题，执行下一个任务
                    {
                        System.out.println("任务" + task.getId() + "检测到CreationImgSketch为空");
                        continue;
                    }
                    task.setCreationImgSketch(creationImgSketch);

                    // 异步执行一个方法，并获取 CompletableFuture 对象
                    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                        CompletableFuture<Void> futureChild = CompletableFuture.runAsync(() -> {
                            // 在这里执行你的异步方法
                            System.out.println("开始执行生成请求" + finalIdleServer.getAddress());

                            try {
                                SdRequestUtils.SdChangeCpt(finalIdleServer.getAddress(), task.getCreationStyle().getCptName());
                            } catch (JsonProcessingException e) {
                                System.out.println(e);
                            }

                            SdRequestUtils.SdCreateImgBySkech(finalIdleServer.getAddress(), task, aiImgPngPath, baseDirectory);
                            // 可以在这里放置任何耗时的操作
                        });
                        futureChild.join();

                        File file = new File(aiImgPngPath);

                        if (!file.exists()) {//如果文件不存在，说明生成失败了,置为等待
                            taskQueueService.setStateWaiting(task.getId());
                        } else {
                            //如果完成了，那么更新数据库
                            CreationImgAi creationImgAi = new CreationImgAi();
                            creationImgAi.setCreationId(creationId);
                            creationImgAi.setProjectId(task.getCreation().getProjectId());
                            creationImgAi.setName(pngName);
                            creationImgAi.setSize(file.length());
                            creationImgAiService.add(creationImgAi);
                            //如果文件存在，说明生成了,置为完成
                            taskQueueService.setStateFinish(task.getId());
                        }
                    });

                } else if (creationCate == 0) {

                    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                        // 异步执行一个方法，并获取 CompletableFuture 对象
                        CompletableFuture<Void> futureChild = CompletableFuture.runAsync(() -> {
                            // 在这里执行你的异步方法
                            System.out.println("开始执行生成请求" + finalIdleServer.getAddress());
                            try {
                                SdRequestUtils.SdChangeCpt(finalIdleServer.getAddress(), task.getCreationStyle().getCptName());
                            } catch (JsonProcessingException e) {
                                System.out.println(e);
                            }
                            SdRequestUtils.SdCreateImgByTxt(finalIdleServer.getAddress(), task, aiImgPngPath);

                            // 可以在这里放置任何耗时的操作
                        });
                        futureChild.join();

                        File file = new File(aiImgPngPath);

                        if (!file.exists()) {//如果文件不存在，说明生成失败了,置为等待
                            taskQueueService.setStateWaiting(task.getId());
                        } else {
                            //如果完成了，那么更新数据库
                            CreationImgAi creationImgAi = new CreationImgAi();
                            creationImgAi.setCreationId(creationId);
                            creationImgAi.setProjectId(task.getCreation().getProjectId());
                            creationImgAi.setName(pngName);
                            creationImgAi.setSize(file.length());
                            creationImgAiService.add(creationImgAi);
                            //如果文件存在，说明生成了,置为完成
                            taskQueueService.setStateFinish(task.getId());
                        }
                    });

                }


                //执行结果存储到creationId相关的创作表中
            } else {
                //如果服务器都繁忙，那么结束遍历任务，继续等待
                break;
            }

        }


    }


}
